// =====================================================================
// FileName : Legal.v 
// Function : A check on legality of various memory reference constructs.
//
// $strobe is like $display: Both are system tasks which print a message 
// to the simulator console. The difference between them will be explained 
// in class later.
//
// -----------------------------------------------------------------------
// Author   : QilinZhao
// Version  : v-1.0
// Date     : 2013-09-10
// E-mail   : forqilin@163.com
// Copyright: QiXin Studio
// =======================================================================

`timescale 1ns/100ps

module Legal; // No need for I/O
parameter HiAddr = 63;
parameter Width  = HiAddr+1;
parameter AnAddr = HiAddr/2;

reg[HiAddr:0]    MemArray[HiAddr:0]; // verilog 2D array models memory.
reg[Width/4-1:0] ByteRegister; //half-word: 16bits
reg[Width/2-1:0] WordRegister;

integer i;

initial
begin
  #0  ByteRegister = 4'h7;
  #0  WordRegister = 4'h3;
  
  // This for loop controls just one statement:
  #1 for (i=0; i<=HiAddr; i=i+1) // i++ is illegal in verilog
       #0.1 MemArray[i] = 1 + i + 1<<i;
	 
  // Use blocking assignments to space out events:
  #5 ByteRegister = ByteRegister + 1;
  #0 $strobe("%04d: ByteRegister=%h", $time, ByteRegister);
  
  #5 ByteRegister =    MemArray[AnAddr];
  #0 $strobe("%04d: ByteRegister=%h Mem[%02d]=%h", $time, ByteRegister, AnAddr,  MemArray[AnAddr]);
  
  #5 ByteRegister =    MemArray[AnAddr][7:0]; // illegal in IEEE1995
  #0 $strobe("%04d: ByteRegister=%h Mem[%02d]=%h", $time, ByteRegister,  AnAddr, MemArray[AnAddr]);
  
  #5 ByteRegister =    MemArray[AnAddr][15:8];
  #0 $strobe("%04d: ByteRegister=%h Mem[%02d]=%h", $time, ByteRegister, AnAddr,  MemArray[AnAddr]);
  
  #5    MemArray[AnAddr-1][Width/2-1:Width/4-1] = WordRegister;
  #0 $strobe("%04d: Mem[%02d]=%h", $time, AnAddr-1,   MemArray[AnAddr-1]);
  
  #5 WordRegister =    MemArray[AnAddr-1][31:0];
  #0 $strobe("%04d: WordRegister=%h Mem[%02d]=%h", $time, WordRegister, AnAddr-1,   MemArray[AnAddr-1]);
  
  #5 $finish;
  end
  
  initial begin
    $vcdpluson();
  end 

endmodule // Legal
